package MetroLab.Train;

import MetroLab.Control.ControlCenter;
import MetroLab.Path.*;
import javax.media.j3d.*;
import javax.vecmath.*;

/**
 *
 * @author plus
 */
public abstract class Train {

    protected TrainDesc MyDesc;
    protected Rail MyRail;
    protected Carriage[] Carriages;
    protected DriverRoom MyDriverRoom;
    
    double D;
    boolean isReversed = false;
    Group TrainRoot = new Group();
    double speed = 80;
    //protected ControlCenter Controller;
    int viewType = 0;
    Light TrainLight;

    public Train(TrainDesc MyDesc, double D, boolean isReversed, Rail MyRail) {
        this.isReversed = isReversed;
        this.MyDesc = MyDesc;
        this.D = D;
        this.MyRail = MyRail;

        TrainLight = new PointLight(true, new Color3f(.7f, .7f, .7f),
                new Point3f(-200f, 800f, 0f), new Point3f(1f, 0, 0));
        TrainLight.setInfluencingBounds(new BoundingSphere(new Point3d(0d, 0d, 0d), 1000));

        TrainLight.setCapability(PointLight.ALLOW_POSITION_WRITE);
        TrainLight.setCapability(PointLight.ALLOW_INFLUENCING_BOUNDS_WRITE);
        TrainRoot.addChild(TrainLight);

        initTrain();
    }

    public Train(TrainDesc MyDesc) {
        this.isReversed = false;
        this.MyDesc = MyDesc;
        this.D = 0;
        //this.MyRail = MyRail;

        TrainLight = new PointLight(true, new Color3f(.7f, .7f, .7f),
                new Point3f(-200f, 800f, 0f), new Point3f(1f, 0, 0));
        TrainLight.setInfluencingBounds(new BoundingSphere(new Point3d(0d, 0d, 0d), 1000));
        TrainLight.setCapability(PointLight.ALLOW_POSITION_WRITE);
        TrainRoot.addChild(TrainLight);

        initTrain();
    }

    abstract void initTrain();  //初始化车辆各部件


    public Group getTrainGroup() {
        return this.TrainRoot;
    }

    public void RMF(double seconds) {
        if (!this.isReversed) {
            D += (speed / 3.6d) * seconds;
        } else {
            D -= (speed / 3.6d) * seconds;
        }
        if (D > (MyRail.getLength()-150d)){
            //this.isReversed = !this.isReversed;
            D = MyRail.getLength()-150d;
            speed=0;
        } else if (D < 0) {
            //this.isReversed = !this.isReversed;
            D = 0;
            speed=0;
        }

        for (int i = 0; i < this.MyDesc.Carriages; i++) {
            this.Carriages[i].RefreshPosition();
        }
        PosPoint pView = new PosPoint();

        if (TrainLight != null) {
            pView.d = D + 140d;
            pView = MyRail.makePath(pView);
            Point3f lightPos = new Point3f((float) pView.pos.x - 200, (float) pView.pos.y + 800f, (float) pView.pos.z);
            Point3d lightPosD= new Point3d( pView.pos.x - 200, pView.pos.y + 800f,  pView.pos.z);
            ((PointLight) TrainLight).setPosition(lightPos);
            TrainLight.setInfluencingBounds(new BoundingSphere(lightPosD, 1000));
        }

        switch (this.viewType) {
            case 0: {
                //PosPoint pView=new PosPoint();
                pView.d = D + 180d;
                pView = MyRail.makePath(pView);
                MetroLab.Control.ControlCenter.setView(//
                        new Vector3f((float) pView.pos.x, (float) pView.pos.y + 2.5f, (float) pView.pos.z),
                        new Vector3f(0f, (float) (pView.AngV - Math.PI / 2), (float) -pView.AngH));
                ControlCenter.orbit.setRotationCenter(pView.pos);
                break;
            }
            case 1: {
                pView.d = D + 200d;
                pView = MyRail.makePath(pView);
                MetroLab.Control.ControlCenter.setView(//
                        new Vector3f((float) pView.pos.x - 4, (float) pView.pos.y + 5f, (float) pView.pos.z),
                        new Vector3f(0f, (float) (pView.AngV + Math.PI / 2), (float) -pView.AngH));
                ControlCenter.orbit.setRotationCenter(pView.pos);
                break;
            }
            case 2:{
                pView.d = (int)(D/300+1)*300d;
                pView = MyRail.makePath(pView);
                MetroLab.Control.ControlCenter.setView(//
                        new Vector3f((float) pView.pos.x + 4, (float) pView.pos.y + 5f, (float) pView.pos.z),
                        new Vector3f(0f, (float) (pView.AngV + Math.PI / 2), 0f));
                ControlCenter.orbit.setRotationCenter(pView.pos);
                break;
            }
            case 3: {
                //pView.d = (int) (D / 300 + 1) * 300d;
                //pView = MyRail.makePath(pView);
                ControlCenter.orbit.setRotationCenter(pView.pos);
                break;
            }
        }
    //System.err.println(D);)0f,
    }

    public void setSpeed(double speed) {
        this.speed = speed;
    }

    public void setViewType(int type) {
        this.viewType = type;
    }
}
